@file:Suppress("unused")

package cn.qfys521.mc_websocket.client

import cn.qfys521.mc_websocket.client.models.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer

/**
 * Management API 封装：将管理协议的 JSON-RPC 方法映射为类型安全的 Kotlin 挂起函数。
 *
 * 约定：
 * - 方法名与远程方法一一对应，如 allowlist -> "minecraft:allowlist"。
 * - 有参请求自动封装为单元素 params 数组，无参则省略 params。
 * - 通知订阅 onXxx 系列方法包装了底层的 onNotification/onRawNotification。
 */
class ManagementApi(private val client: ManagementWsClient) {

    /** 获取当前白名单（minecraft:allowlist）。 */
    suspend fun allowlist(): List<Player> =
        client.callNoParams("minecraft:allowlist", ListSerializer(Player.serializer()))

    /** 覆盖白名单（minecraft:allowlist/set）。 */
    suspend fun allowlistSet(players: List<Player>): List<Player> =
        client.call(
            method = "minecraft:allowlist/set",
            params = players,
            paramsSerializer = ListSerializer(Player.serializer()),
            resultDeserializer = ListSerializer(Player.serializer())
        )

    /** 添加到白名单（minecraft:allowlist/add）。 */
    suspend fun allowlistAdd(add: List<Player>): List<Player> =
        client.call(
            method = "minecraft:allowlist/add",
            params = add,
            paramsSerializer = ListSerializer(Player.serializer()),
            resultDeserializer = ListSerializer(Player.serializer())
        )

    /** 从白名单移除（minecraft:allowlist/remove）。 */
    suspend fun allowlistRemove(remove: List<Player>): List<Player> =
        client.call(
            method = "minecraft:allowlist/remove",
            params = remove,
            paramsSerializer = ListSerializer(Player.serializer()),
            resultDeserializer = ListSerializer(Player.serializer())
        )

    /** 清空白名单（minecraft:allowlist/clear）。 */
    suspend fun allowlistClear(): List<Player> =
        client.callNoParams("minecraft:allowlist/clear", ListSerializer(Player.serializer()))

    /** 获取封禁玩家列表（minecraft:bans）。 */
    suspend fun bans(): List<UserBan> =
        client.callNoParams("minecraft:bans", ListSerializer(UserBan.serializer()))

    /** 覆盖封禁玩家列表（minecraft:bans/set）。 */
    suspend fun bansSet(bans: List<UserBan>): List<UserBan> =
        client.call(
            method = "minecraft:bans/set",
            params = bans,
            paramsSerializer = ListSerializer(UserBan.serializer()),
            resultDeserializer = ListSerializer(UserBan.serializer())
        )

    /** 添加封禁玩家（minecraft:bans/add）。 */
    suspend fun bansAdd(add: List<UserBan>): List<UserBan> =
        client.call(
            method = "minecraft:bans/add",
            params = add,
            paramsSerializer = ListSerializer(UserBan.serializer()),
            resultDeserializer = ListSerializer(UserBan.serializer())
        )

    /** 移除封禁玩家（minecraft:bans/remove）。 */
    suspend fun bansRemove(remove: List<Player>): List<UserBan> =
        client.call(
            method = "minecraft:bans/remove",
            params = remove,
            paramsSerializer = ListSerializer(Player.serializer()),
            resultDeserializer = ListSerializer(UserBan.serializer())
        )

    /** 清空封禁玩家（minecraft:bans/clear）。 */
    suspend fun bansClear(): List<UserBan> =
        client.callNoParams("minecraft:bans/clear", ListSerializer(UserBan.serializer()))

    /** 获取封禁 IP 列表（minecraft:ip_bans）。 */
    suspend fun ipBans(): List<Player> =
        client.callNoParams("minecraft:ip_bans", ListSerializer(Player.serializer()))

    /** 覆盖封禁 IP 列表（minecraft:ip_bans/set）。 */
    suspend fun ipBansSet(banlist: List<IpBan>): List<IpBan> =
        client.call(
            method = "minecraft:ip_bans/set",
            params = banlist,
            paramsSerializer = ListSerializer(IpBan.serializer()),
            resultDeserializer = ListSerializer(IpBan.serializer())
        )

    /** 添加封禁 IP（minecraft:ip_bans/add）。 */
    suspend fun ipBansAdd(add: List<IncomingIpBan>): List<IpBan> =
        client.call(
            method = "minecraft:ip_bans/add",
            params = add,
            paramsSerializer = ListSerializer(IncomingIpBan.serializer()),
            resultDeserializer = ListSerializer(IpBan.serializer())
        )

    /** 解除封禁 IP（minecraft:ip_bans/remove）。 */
    suspend fun ipBansRemove(ip: List<String>): List<IpBan> =
        client.call(
            method = "minecraft:ip_bans/remove",
            params = ip,
            paramsSerializer = ListSerializer(String.serializer()),
            resultDeserializer = ListSerializer(IpBan.serializer())
        )

    /** 清空封禁 IP（minecraft:ip_bans/clear）。 */
    suspend fun ipBansClear(): List<IpBan> =
        client.callNoParams("minecraft:ip_bans/clear", ListSerializer(IpBan.serializer()))

    /** 获取在线玩家列表（minecraft:players）。 */
    suspend fun players(): List<Player> =
        client.callNoParams("minecraft:players", ListSerializer(Player.serializer()))

    /** 踢出玩家（minecraft:players/kick）。 */
    suspend fun playersKick(kick: List<KickPlayer>): List<Player> =
        client.call(
            method = "minecraft:players/kick",
            params = kick,
            paramsSerializer = ListSerializer(KickPlayer.serializer()),
            resultDeserializer = ListSerializer(Player.serializer())
        )

    /** 获取管理员列表（minecraft:operators）。 */
    suspend fun operators(): List<Operator> =
        client.callNoParams("minecraft:operators", ListSerializer(Operator.serializer()))

    /** 覆盖管理员列表（minecraft:operators/set）。 */
    suspend fun operatorsSet(operators: List<Operator>): List<Operator> =
        client.call(
            method = "minecraft:operators/set",
            params = operators,
            paramsSerializer = ListSerializer(Operator.serializer()),
            resultDeserializer = ListSerializer(Operator.serializer())
        )

    /** 添加管理员（minecraft:operators/add）。 */
    suspend fun operatorsAdd(add: List<Operator>): List<Operator> =
        client.call(
            method = "minecraft:operators/add",
            params = add,
            paramsSerializer = ListSerializer(Operator.serializer()),
            resultDeserializer = ListSerializer(Operator.serializer())
        )

    /** 移除管理员（minecraft:operators/remove）。 */
    suspend fun operatorsRemove(remove: List<Player>): List<Operator> =
        client.call(
            method = "minecraft:operators/remove",
            params = remove,
            paramsSerializer = ListSerializer(Player.serializer()),
            resultDeserializer = ListSerializer(Operator.serializer())
        )

    /** 清空管理员（minecraft:operators/clear）。 */
    suspend fun operatorsClear(): List<Operator> =
        client.callNoParams("minecraft:operators/clear", ListSerializer(Operator.serializer()))

    /** 获取服务端状态（minecraft:server/status）。 */
    suspend fun serverStatus(): ServerState =
        client.callNoParams("minecraft:server/status", ServerState.serializer())

    /** 触发保存（minecraft:server/save）。 */
    suspend fun serverSave(flush: Boolean): Boolean =
        client.call(
            method = "minecraft:server/save",
            params = flush,
            paramsSerializer = Boolean.serializer(),
            resultDeserializer = Boolean.serializer()
        )

    /** 停止服务端（minecraft:server/stop）。 */
    suspend fun serverStop(): Boolean =
        client.callNoParams("minecraft:server/stop", Boolean.serializer())

    /** 发送系统消息（minecraft:server/system_message）。 */
    suspend fun serverSystemMessage(message: SystemMessage): Boolean =
        client.call(
            method = "minecraft:server/system_message",
            params = message,
            paramsSerializer = SystemMessage.serializer(),
            resultDeserializer = Boolean.serializer()
        )

    
    private suspend fun <T> getSetting(method: String, deserializer: KSerializer<T>): T =
        client.callNoParams(method, deserializer)

    private suspend fun <T> setSetting(method: String, value: T, serializer: KSerializer<T>): T =
        client.call(method, value, serializer, serializer)

    
    /** 查询是否自动保存（serversettings/autosave）。 */
    suspend fun autosave(): Boolean = getSetting("minecraft:serversettings/autosave", Boolean.serializer())
    /** 设置是否自动保存（serversettings/autosave/set）。 */
    suspend fun autosaveSet(enable: Boolean): Boolean = setSetting("minecraft:serversettings/autosave/set", enable, Boolean.serializer())

    /** 查询难度（serversettings/difficulty）。 */
    suspend fun difficulty(): String = getSetting("minecraft:serversettings/difficulty", String.serializer())
    /** 设置难度（serversettings/difficulty/set）。 */
    suspend fun difficultySet(value: String): String = setSetting("minecraft:serversettings/difficulty/set", value, String.serializer())

    /** 查询是否强制白名单（serversettings/enforce_allowlist）。 */
    suspend fun enforceAllowlist(): Boolean = getSetting("minecraft:serversettings/enforce_allowlist", Boolean.serializer())
    /** 设置是否强制白名单（serversettings/enforce_allowlist/set）。 */
    suspend fun enforceAllowlistSet(enforce: Boolean): Boolean = setSetting("minecraft:serversettings/enforce_allowlist/set", enforce, Boolean.serializer())

    /** 查询是否启用白名单（serversettings/use_allowlist）。 */
    suspend fun useAllowlist(): Boolean = getSetting("minecraft:serversettings/use_allowlist", Boolean.serializer())
    /** 设置是否启用白名单（serversettings/use_allowlist/set）。 */
    suspend fun useAllowlistSet(use: Boolean): Boolean = setSetting("minecraft:serversettings/use_allowlist/set", use, Boolean.serializer())

    /** 查询最大玩家数（serversettings/max_players）。 */
    suspend fun maxPlayers(): Int = getSetting("minecraft:serversettings/max_players", Int.serializer())
    /** 设置最大玩家数（serversettings/max_players/set）。 */
    suspend fun maxPlayersSet(max: Int): Int = setSetting("minecraft:serversettings/max_players/set", max, Int.serializer())

    /** 查询空服暂停秒数（serversettings/pause_when_empty_seconds）。 */
    suspend fun pauseWhenEmptySeconds(): Int = getSetting("minecraft:serversettings/pause_when_empty_seconds", Int.serializer())
    /** 设置空服暂停秒数（serversettings/pause_when_empty_seconds/set）。 */
    suspend fun pauseWhenEmptySecondsSet(seconds: Int): Int = setSetting("minecraft:serversettings/pause_when_empty_seconds/set", seconds, Int.serializer())

    /** 查询空闲踢出时间（serversettings/player_idle_timeout）。 */
    suspend fun playerIdleTimeout(): Int = getSetting("minecraft:serversettings/player_idle_timeout", Int.serializer())
    /** 设置空闲踢出时间（serversettings/player_idle_timeout/set）。 */
    suspend fun playerIdleTimeoutSet(seconds: Int): Int = setSetting("minecraft:serversettings/player_idle_timeout/set", seconds, Int.serializer())

    /** 查询是否允许飞行（serversettings/allow_flight）。 */
    suspend fun allowFlight(): Boolean = getSetting("minecraft:serversettings/allow_flight", Boolean.serializer())
    /** 设置是否允许飞行（serversettings/allow_flight/set）。 */
    suspend fun allowFlightSet(allow: Boolean): Boolean = setSetting("minecraft:serversettings/allow_flight/set", allow, Boolean.serializer())

    /** 查询 MOTD（serversettings/motd）。 */
    suspend fun motd(): String = getSetting("minecraft:serversettings/motd", String.serializer())
    /** 设置 MOTD（serversettings/motd/set）。 */
    suspend fun motdSet(message: String): String = setSetting("minecraft:serversettings/motd/set", message, String.serializer())

    /** 查询出生点保护半径（serversettings/spawn_protection_radius）。 */
    suspend fun spawnProtectionRadius(): Int = getSetting("minecraft:serversettings/spawn_protection_radius", Int.serializer())
    /** 设置出生点保护半径（serversettings/spawn_protection_radius/set）。 */
    suspend fun spawnProtectionRadiusSet(radius: Int): Int = setSetting("minecraft:serversettings/spawn_protection_radius/set", radius, Int.serializer())

    /** 查询是否强制默认游戏模式（serversettings/force_game_mode）。 */
    suspend fun forceGameMode(): Boolean = getSetting("minecraft:serversettings/force_game_mode", Boolean.serializer())
    /** 设置是否强制默认游戏模式（serversettings/force_game_mode/set）。 */
    suspend fun forceGameModeSet(force: Boolean): Boolean = setSetting("minecraft:serversettings/force_game_mode/set", force, Boolean.serializer())

    /** 查询默认游戏模式（serversettings/game_mode）。 */
    suspend fun gameMode(): String = getSetting("minecraft:serversettings/game_mode", String.serializer())
    /** 设置默认游戏模式（serversettings/game_mode/set）。 */
    suspend fun gameModeSet(mode: String): String = setSetting("minecraft:serversettings/game_mode/set", mode, String.serializer())

    /** 查询渲染距离（serversettings/view_distance）。 */
    suspend fun viewDistance(): Int = getSetting("minecraft:serversettings/view_distance", Int.serializer())
    /** 设置渲染距离（serversettings/view_distance/set）。 */
    suspend fun viewDistanceSet(distance: Int): Int = setSetting("minecraft:serversettings/view_distance/set", distance, Int.serializer())

    /** 查询模拟距离（serversettings/simulation_distance）。 */
    suspend fun simulationDistance(): Int = getSetting("minecraft:serversettings/simulation_distance", Int.serializer())
    /** 设置模拟距离（serversettings/simulation_distance/set）。 */
    suspend fun simulationDistanceSet(distance: Int): Int = setSetting("minecraft:serversettings/simulation_distance/set", distance, Int.serializer())

    /** 查询是否接收转服（serversettings/accept_transfers）。 */
    suspend fun acceptTransfers(): Boolean = getSetting("minecraft:serversettings/accept_transfers", Boolean.serializer())
    /** 设置是否接收转服（serversettings/accept_transfers/set）。 */
    suspend fun acceptTransfersSet(accept: Boolean): Boolean = setSetting("minecraft:serversettings/accept_transfers/set", accept, Boolean.serializer())

    /** 查询心跳间隔（serversettings/status_heartbeat_interval）。 */
    suspend fun statusHeartbeatInterval(): Int = getSetting("minecraft:serversettings/status_heartbeat_interval", Int.serializer())
    /** 设置心跳间隔（serversettings/status_heartbeat_interval/set）。 */
    suspend fun statusHeartbeatIntervalSet(seconds: Int): Int = setSetting("minecraft:serversettings/status_heartbeat_interval/set", seconds, Int.serializer())

    /** 查询管理员默认权限等级（serversettings/operator_user_permission_level）。 */
    suspend fun operatorUserPermissionLevel(): Int = getSetting("minecraft:serversettings/operator_user_permission_level", Int.serializer())
    /** 设置管理员默认权限等级（serversettings/operator_user_permission_level/set）。 */
    suspend fun operatorUserPermissionLevelSet(level: Int): Int = setSetting("minecraft:serversettings/operator_user_permission_level/set", level, Int.serializer())

    /** 查询是否隐藏在线玩家（serversettings/hide_online_players）。 */
    suspend fun hideOnlinePlayers(): Boolean = getSetting("minecraft:serversettings/hide_online_players", Boolean.serializer())
    /** 设置是否隐藏在线玩家（serversettings/hide_online_players/set）。 */
    suspend fun hideOnlinePlayersSet(hide: Boolean): Boolean = setSetting("minecraft:serversettings/hide_online_players/set", hide, Boolean.serializer())

    /** 查询是否允许状态阶段（serversettings/status_replies）。 */
    suspend fun statusReplies(): Boolean = getSetting("minecraft:serversettings/status_replies", Boolean.serializer())
    /** 设置是否允许状态阶段（serversettings/status_replies/set）。 */
    suspend fun statusRepliesSet(enable: Boolean): Boolean = setSetting("minecraft:serversettings/status_replies/set", enable, Boolean.serializer())

    /** 查询实体广播距离百分比（serversettings/entity_broadcast_range）。 */
    suspend fun entityBroadcastRange(): Int = getSetting("minecraft:serversettings/entity_broadcast_range", Int.serializer())
    /** 设置实体广播距离百分比（serversettings/entity_broadcast_range/set）。 */
    suspend fun entityBroadcastRangeSet(percentagePoints: Int): Int = setSetting("minecraft:serversettings/entity_broadcast_range/set", percentagePoints, Int.serializer())

    
    /** 列出所有有效游戏规则（minecraft:gamerules）。 */
    suspend fun gamerules(): List<TypedGameRule> =
        client.callNoParams("minecraft:gamerules", ListSerializer(TypedGameRule.serializer()))

    /** 修改游戏规则（minecraft:gamerules/update）。 */
    suspend fun gamerulesUpdate(rule: UntypedGameRule): TypedGameRule =
        client.call(
            method = "minecraft:gamerules/update",
            params = rule,
            paramsSerializer = UntypedGameRule.serializer(),
            resultDeserializer = TypedGameRule.serializer()
        )

    
    /** 通知：server/started。 */
    fun onServerStarted(cb: () -> Unit) = client.onRawNotification("notification:server/started") { cb() }
    /** 通知：server/stopping。 */
    fun onServerStopping(cb: () -> Unit) = client.onRawNotification("notification:server/stopping") { cb() }
    /** 通知：server/saving。 */
    fun onServerSaving(cb: () -> Unit) = client.onRawNotification("notification:server/saving") { cb() }
    /** 通知：server/saved。 */
    fun onServerSaved(cb: () -> Unit) = client.onRawNotification("notification:server/saved") { cb() }

    /** 通知：players/joined。 */
    fun onPlayersJoined(cb: (Player?) -> Unit) =
        client.onNotification("notification:players/joined", Player.serializer(), cb)

    /** 通知：players/left。 */
    fun onPlayersLeft(cb: (Player?) -> Unit) =
        client.onNotification("notification:players/left", Player.serializer(), cb)

    /** 通知：operators/added。 */
    fun onOperatorsAdded(cb: (Operator?) -> Unit) =
        client.onNotification("notification:operators/added", Operator.serializer(), cb)

    /** 通知：operators/removed。 */
    fun onOperatorsRemoved(cb: (Operator?) -> Unit) =
        client.onNotification("notification:operators/removed", Operator.serializer(), cb)

    /** 通知：allowlist/added。 */
    fun onAllowlistAdded(cb: (Player?) -> Unit) =
        client.onNotification("notification:allowlist/added", Player.serializer(), cb)

    /** 通知：allowlist/removed。 */
    fun onAllowlistRemoved(cb: (Player?) -> Unit) =
        client.onNotification("notification:allowlist/removed", Player.serializer(), cb)

    /** 通知：ip_bans/added。 */
    fun onIpBansAdded(cb: (IpBan?) -> Unit) =
        client.onNotification("notification:ip_bans/added", IpBan.serializer(), cb)

    /** 通知：ip_bans/removed。 */
    fun onIpBansRemoved(cb: (String?) -> Unit) =
        client.onNotification("notification:ip_bans/removed", String.serializer(), cb)

    /** 通知：bans/added。 */
    fun onBansAdded(cb: (UserBan?) -> Unit) =
        client.onNotification("notification:bans/added", UserBan.serializer(), cb)

    /** 通知：bans/removed。 */
    fun onBansRemoved(cb: (Player?) -> Unit) =
        client.onNotification("notification:bans/removed", Player.serializer(), cb)

    /** 通知：gamerules/updated。 */
    fun onGamerulesUpdated(cb: (TypedGameRule?) -> Unit) =
        client.onNotification("notification:gamerules/updated", TypedGameRule.serializer(), cb)

    /** 通知：server/status（心跳）。 */
    fun onServerStatus(cb: (ServerState?) -> Unit) =
        client.onNotification("notification:server/status", ServerState.serializer(), cb)
}
